import IconFont from '@/IconFontAl';
import defPic from '@/assets/imgs/default_head.png';
import { Checkbox, Empty, Radio, Skeleton } from 'antd';
import type { CheckboxChangeEvent } from 'antd/es/checkbox';
import classNames from 'classnames';
import {
  forwardRef,
  useImperativeHandle,
  useLayoutEffect,
  useMemo,
  useState,
} from 'react';
import CrumbList from './CrumbList';
import {
  ChoiceListRef,
  CrumbItem,
  IRoleDetail,
  RoleChoiceListProps,
  TChoiceStaffValue,
  TRole,
  TRoleGroupItem,
  roleRequestParams,
} from './interface';

import { getOtherCheckboxStaObj } from './utils';

const RoleChoiceList = forwardRef<ChoiceListRef, RoleChoiceListProps>(
  (props, ref) => {
    const {
      defaultValue,
      onRoleChoiceChange,
      onRoleChoiceChangeBatch,
      roleRequest,
      requestParams,
      keyWord,
      prefixCls,
      onlyChoicePeople,
      choiceBtn,
    } = props;
    const { entId, entName } = requestParams;
    const [selectedValues, setSelectedValues] = useState<TChoiceStaffValue[]>(
      defaultValue || [],
    );
    const [loading, showLoading] = useState<boolean>(false);

    //面包屑
    const [crumbList, setCrumbList] = useState<CrumbItem[]>([
      { entId, name: entName, guid: entId },
    ]);

    // 定义列表数据
    const [roleGroupList, setRoleGroupList] = useState<
      IRoleDetail['roleGroupList']
    >([]);
    const [roleStaffList, setRoleStaffList] = useState<IRoleDetail['plist']>(
      [],
    );

    const getRoleList = (params: roleRequestParams) => {
      showLoading(true);
      return roleRequest(params)
        .then((resData: IRoleDetail | undefined) => {
          //resData.roleGroupList 和resData.plist不会同时存在(角色组子级只能是角色，不可能是人)
          // console.log('--RoleChoiceList--resData--:', resData);
          const { roleGroupList, plist } = resData || {};
          const currRoleOrEntdId = params.roleId || params.entId;

          roleGroupList?.forEach((groupItem) => {
            groupItem.rlist?.forEach((rItem) => {
              rItem.guid = rItem.roleId;
              rItem.name = rItem.roleName;
              rItem.combineId = `${currRoleOrEntdId}_${rItem.guid}`;
            });
          });
          setRoleGroupList(roleGroupList || []);

          // 注：如果同一个人有不同角色，采用combineId = personId + roleId 标记唯一性,crumbList[0].guid === entId; 但是crumbList.length === 1时，只能选角色组下的角色
          const tempPlist = (plist || []).map((pItem) => ({
            ...pItem,
            combineId: `${params.roleId}_${pItem.personId}`,
          }));
          setRoleStaffList(tempPlist);
        })
        .finally(() => {
          showLoading(false);
        });
    };

    //搜索
    const handleSearch = (keyWord: string | undefined) => {
      const roleId = crumbList[crumbList.length - 1].entId
        ? undefined
        : crumbList[crumbList.length - 1].guid;
      getRoleList({ entId, roleId, keyWord });
    };
    //删除选中
    const handleDelete = (selectedItem: TChoiceStaffValue) => {
      // console.log(
      //   '--RoleChoiceList--handleDelete--selectedItem--:',
      //   selectedItem,
      // );
      const tempSelectedValues = selectedValues;
      const exitIndex = tempSelectedValues.findIndex(
        (valItem) => valItem.combineId === selectedItem.combineId,
      );
      if (exitIndex > -1) {
        tempSelectedValues.splice(exitIndex, 1);
        onRoleChoiceChange('delete', selectedItem);
        setSelectedValues([...tempSelectedValues]);
      }
    };

    useImperativeHandle(ref, () => ({
      search: handleSearch,
      delete: handleDelete,
      resetSelectedValues: (newSelValues: TChoiceStaffValue[]) => {
        setSelectedValues(newSelValues);
      },
    }));

    useLayoutEffect(() => {
      getRoleList({ entId });
    }, []);

    //面包屑
    const handleCrumbClick = (currCurmb: CrumbItem) => {
      // console.log('--currCurmb--:', currCurmb);
      const { guid, entId: crumbEntId } = currCurmb;
      const currIndex = crumbList.findIndex(
        (crumbItem) => crumbItem.guid === guid,
      );
      if (currIndex > -1) {
        crumbList.splice(currIndex + 1);
        setCrumbList([...crumbList]);
        getRoleList({ entId, roleId: crumbEntId ? undefined : guid, keyWord });
      }
    };

    //下一级
    const handRoleChild = (e: React.MouseEvent, roleItem: TRole) => {
      e.stopPropagation();
      const { guid, name } = roleItem;
      getRoleList({ entId, roleId: guid, keyWord }).then(() => {
        crumbList.push({ guid: guid!, name: name! });
        setCrumbList(crumbList);
      });
    };

    //全选
    const handleAllChoiceChange = (e: CheckboxChangeEvent) => {
      // setChoiceAll(e.target.checked);
      const allChecked = e.target.checked;
      const tempOperationList: TChoiceStaffValue[] = [];
      const tempSelectedValues = selectedValues;
      if (!onlyChoicePeople) {
        const roleList = roleGroupList!.reduce(
          (
            prev: TRole[],
            curr: TRoleGroupItem,
            index: number,
            array: IRoleDetail['roleGroupList'],
          ) => {
            const tempTList = curr.rlist || [];
            prev = [...prev, ...tempTList];
            return prev;
          },
          [],
        );

        roleList.forEach((roleItem) => {
          const existRoleItemIndex = tempSelectedValues.findIndex(
            (selItem) => selItem.combineId === roleItem.combineId,
          );
          const tempSelItem: TChoiceStaffValue = {
            choiceType: 'role',
            guid: roleItem.guid,
            name: roleItem.name,
            combineId: roleItem.combineId!,
          };
          if (existRoleItemIndex < 0 && allChecked) {
            //选中不存在
            tempSelectedValues.push(tempSelItem);
            tempOperationList.push(tempSelItem);
          }
          if (existRoleItemIndex > -1 && !allChecked) {
            //取消选中已存在
            tempSelectedValues.splice(existRoleItemIndex, 1);
            tempOperationList.push(tempSelItem);
          }
        });
      }
      roleStaffList!.forEach((roleStaffItem) => {
        const existRoleStaffItemIndex = selectedValues.findIndex(
          (selItem) => selItem.combineId === roleStaffItem.combineId,
        );
        const tempSelItem: TChoiceStaffValue = {
          choiceType: 'role',
          ...roleStaffItem,
        };
        if (existRoleStaffItemIndex < 0 && allChecked) {
          tempSelectedValues.push(tempSelItem);
          tempOperationList.push(tempSelItem);
        }
        if (existRoleStaffItemIndex > -1 && !allChecked) {
          tempSelectedValues.splice(existRoleStaffItemIndex, 1);
          tempOperationList.push(tempSelItem);
        }
      });

      onRoleChoiceChangeBatch(allChecked ? 'add' : 'delete', tempOperationList);
      setSelectedValues([...tempSelectedValues]);
    };

    //当前行选中、取消选中
    const choiceItem = (
      type: 'guid' | 'personId',
      item: any, //Partial<TRole & TPerson>,
    ) => {
      if (type === 'guid' && onlyChoicePeople) return;
      let tempSelectedValues = selectedValues;
      const exitIndex = tempSelectedValues.findIndex(
        (valItem) => valItem.combineId === item.combineId,
      );
      const tempValItem: TChoiceStaffValue =
        type === 'guid'
          ? {
              choiceType: 'role',
              guid: item.guid,
              name: item.name,
              combineId: item.combineId,
            }
          : { choiceType: 'role', ...item };
      if (exitIndex < 0) {
        if (choiceBtn === 'checkbox') {
          tempSelectedValues.push(tempValItem);
        } else {
          tempSelectedValues = [tempValItem];
        }
      } else {
        tempSelectedValues.splice(exitIndex, 1);
      }
      onRoleChoiceChange(exitIndex < 0 ? 'add' : 'delete', tempValItem);
      setSelectedValues([...tempSelectedValues]);
    };

    //全选checkbox是否显示
    const allCheckBoxShow = useMemo(() => {
      let tempShow = false;
      if (choiceBtn === 'checkbox') {
        if (onlyChoicePeople) {
          if (roleStaffList!.length > 0) {
            tempShow = true;
          }
        } else {
          if (roleGroupList!.length > 0 || roleStaffList!.length > 0) {
            tempShow = true;
          }
        }
      }
      return tempShow;
    }, [onlyChoicePeople, choiceBtn, roleGroupList, roleStaffList]);

    return (
      <div className={`${prefixCls}-choice`}>
        <CrumbList
          crumbList={crumbList}
          onCrumbClick={handleCrumbClick}
          prefixCls={prefixCls}
        />
        {allCheckBoxShow && (
          <Checkbox
            onChange={handleAllChoiceChange}
            indeterminate={
              getOtherCheckboxStaObj(
                'role',
                selectedValues,
                roleGroupList,
                roleStaffList || [],
                onlyChoicePeople,
              ).indeterminate
            }
            checked={
              getOtherCheckboxStaObj(
                'role',
                selectedValues,
                roleGroupList,
                roleStaffList || [],
                onlyChoicePeople,
              ).checked
            }
            style={{ marginLeft: '5px' }}
          >
            全选
          </Checkbox>
        )}
        <ul className="choice_list">
          <Skeleton
            loading={loading}
            active
            paragraph={{ rows: 4, width: 296 }}
            title={false}
          >
            {roleGroupList?.map((groupItem) => (
              <li className="list_group_item" key={groupItem.groupId}>
                <div className="group_item_name">
                  <IconFont type="icon-jue_se" className="name_icon" />
                  <p className="name_text">{groupItem.name}</p>
                </div>
                <ul className="group_item_child">
                  {groupItem.rlist?.map((roleItem) => (
                    <li
                      key={roleItem.combineId}
                      className="list_other_item"
                      onClick={() => {
                        choiceItem('guid', roleItem);
                      }}
                    >
                      {choiceBtn === 'checkbox' && !onlyChoicePeople && (
                        <Checkbox
                          checked={
                            selectedValues.findIndex(
                              (valItem) => valItem.guid === roleItem.guid,
                            ) > -1
                              ? true
                              : false
                          }
                          style={{ marginLeft: '5px' }}
                        />
                      )}

                      {choiceBtn === 'radio' && !onlyChoicePeople && (
                        <Radio
                          checked={
                            selectedValues.findIndex(
                              (valItem) => valItem.guid === roleItem.guid,
                            ) > -1
                              ? true
                              : false
                          }
                          style={{ marginLeft: '5px', marginInlineEnd: '0px' }}
                        />
                      )}
                      <div
                        className="item_center"
                        style={{ marginLeft: onlyChoicePeople ? '5px' : '0px' }}
                      >
                        <p className="center_text">{roleItem.name}</p>
                      </div>
                      <p
                        className={classNames('item_right', {
                          ['disabled']:
                            !roleItem.roleNum ||
                            selectedValues.findIndex(
                              (valItem) => valItem.guid === roleItem.guid,
                            ) > -1,
                        })}
                        onClick={(e) => {
                          roleItem.roleNum &&
                            selectedValues.findIndex(
                              (valItem) => valItem.guid === roleItem.guid,
                            ) < 0 &&
                            handRoleChild(e, roleItem);
                        }}
                      >
                        下级
                      </p>
                    </li>
                  ))}
                </ul>
              </li>
            ))}
            {roleStaffList!.map((roleStaffItem) => (
              <li
                key={roleStaffItem.combineId}
                className="list_staff_item"
                onClick={() => {
                  choiceItem('personId', roleStaffItem);
                }}
              >
                {choiceBtn === 'checkbox' ? (
                  <Checkbox
                    checked={
                      selectedValues.findIndex(
                        (valItem) =>
                          valItem.combineId === roleStaffItem.combineId,
                      ) > -1
                        ? true
                        : false
                    }
                    style={{ marginLeft: '5px' }}
                  />
                ) : (
                  <Radio
                    checked={
                      selectedValues.findIndex(
                        (valItem) =>
                          valItem.combineId === roleStaffItem.combineId,
                      ) > -1
                        ? true
                        : false
                    }
                    style={{ marginLeft: '5px', marginInlineEnd: '0px' }}
                  />
                )}
                <div className="item_person">
                  <img
                    className="person_avatar"
                    src={roleStaffItem.hdpic || defPic}
                    alt="头像"
                  />
                  <p className="person_text">
                    <span>{roleStaffItem.personName}</span>
                    <span>({roleStaffItem.phone})</span>
                  </p>
                </div>
              </li>
            ))}
            {!loading &&
              roleGroupList!.length <= 0 &&
              roleStaffList!.length <= 0 && (
                <Empty
                  image={Empty.PRESENTED_IMAGE_SIMPLE}
                  description={false}
                />
              )}
          </Skeleton>
        </ul>
      </div>
    );
  },
);

export default RoleChoiceList;
